/**
 * 文件服务
 * 处理文件相关的IPC通信
 */
import { BaseIPCService, ServiceResult, createSuccessResult, createErrorResult } from './base/ipc.service'

/**
 * 文件信息接口
 */
export interface FileInfo {
  name: string
  path: string
  isFile?: boolean
  isDirectory?: boolean
  size?: number
  createdAt?: Date
  modifiedAt?: Date
  error?: string
}

/**
 * 资源数据接口
 */
export interface AssetData {
  id: string
  name: string
  type: 'image' | 'audio' | 'video'
  path: string
  size: number
  duration?: number
  resolution?: { width: number; height: number }
  thumbnail?: string
  metadata?: any
}

/**
 * 文件服务类
 */
export class FileService extends BaseIPCService {
  /**
   * 获取应用数据目录
   */
  async getAppDataPath(): Promise<ServiceResult<string>> {
    try {
      this.log('获取应用数据目录')

      const result = await this.invoke<string>('get-app-data-path')
      
      this.log('获取应用数据目录成功', { path: result })
      return createSuccessResult(result, '获取应用数据目录成功')

    } catch (error) {
      this.logError('获取应用数据目录', error)
      return createErrorResult(error, '获取应用数据目录失败')
    }
  }

  /**
   * 读取文件
   */
  async readFile(filePath: string, encoding: BufferEncoding = 'utf8'): Promise<ServiceResult<string>> {
    try {
      this.validateRequired({ filePath }, ['filePath'])
      
      this.log('读取文件', { filePath, encoding })

      const result = await this.invoke<{ success: boolean; data?: string; error?: string }>('read-file', filePath, encoding)
      
      if (result.success && result.data !== undefined) {
        this.log('读取文件成功', { filePath, dataLength: result.data.length })
        return createSuccessResult(result.data, '文件读取成功')
      } else {
        throw new Error(result.error || '文件读取失败')
      }

    } catch (error) {
      this.logError('读取文件', error, { filePath, encoding })
      return createErrorResult(error, '读取文件失败')
    }
  }

  /**
   * 写入文件
   */
  async writeFile(filePath: string, data: string, encoding: BufferEncoding = 'utf8'): Promise<ServiceResult<void>> {
    try {
      this.validateRequired({ filePath, data }, ['filePath', 'data'])
      
      this.log('写入文件', { filePath, encoding, dataLength: data.length })

      const result = await this.invoke<{ success: boolean; error?: string }>('write-file', filePath, data, encoding)
      
      if (result.success) {
        this.log('写入文件成功', { filePath })
        return createSuccessResult(undefined, '文件写入成功')
      } else {
        throw new Error(result.error || '文件写入失败')
      }

    } catch (error) {
      this.logError('写入文件', error, { filePath, encoding })
      return createErrorResult(error, '写入文件失败')
    }
  }

  /**
   * 检查文件是否存在
   */
  async fileExists(filePath: string): Promise<ServiceResult<boolean>> {
    try {
      this.validateRequired({ filePath }, ['filePath'])
      
      this.log('检查文件是否存在', { filePath })

      const result = await this.invoke<{ exists: boolean }>('file-exists', filePath)
      
      this.log('检查文件是否存在完成', { filePath, exists: result.exists })
      return createSuccessResult(result.exists, result.exists ? '文件存在' : '文件不存在')

    } catch (error) {
      this.logError('检查文件是否存在', error, { filePath })
      return createErrorResult(error, '检查文件是否存在失败')
    }
  }

  /**
   * 获取文件信息
   */
  async getFileInfo(filePath: string): Promise<ServiceResult<FileInfo>> {
    try {
      this.validateRequired({ filePath }, ['filePath'])
      
      this.log('获取文件信息', { filePath })

      const result = await this.invoke<{
        success: boolean
        isFile?: boolean
        isDirectory?: boolean
        size?: number
        createdAt?: Date
        modifiedAt?: Date
        accessedAt?: Date
        error?: string
      }>('get-file-info', filePath)
      
      if (result.success) {
        const fileInfo: FileInfo = {
          name: filePath.split('/').pop() || filePath,
          path: filePath,
          isFile: result.isFile,
          isDirectory: result.isDirectory,
          size: result.size,
          createdAt: result.createdAt,
          modifiedAt: result.modifiedAt
        }
        
        this.log('获取文件信息成功', { filePath, isFile: result.isFile, size: result.size })
        return createSuccessResult(fileInfo, '获取文件信息成功')
      } else {
        throw new Error(result.error || '获取文件信息失败')
      }

    } catch (error) {
      this.logError('获取文件信息', error, { filePath })
      return createErrorResult(error, '获取文件信息失败')
    }
  }

  /**
   * 列出目录内容
   */
  async listDirectory(dirPath: string): Promise<ServiceResult<FileInfo[]>> {
    try {
      this.validateRequired({ dirPath }, ['dirPath'])
      
      this.log('列出目录内容', { dirPath })

      const result = await this.invoke<{
        success: boolean
        files?: FileInfo[]
        error?: string
      }>('list-directory', dirPath)
      
      if (result.success && result.files) {
        this.log('列出目录内容成功', { dirPath, fileCount: result.files.length })
        return createSuccessResult(result.files, `目录包含 ${result.files.length} 个项目`)
      } else {
        throw new Error(result.error || '列出目录内容失败')
      }

    } catch (error) {
      this.logError('列出目录内容', error, { dirPath })
      return createErrorResult(error, '列出目录内容失败')
    }
  }

  /**
   * 删除文件
   */
  async deleteFile(filePath: string): Promise<ServiceResult<void>> {
    try {
      this.validateRequired({ filePath }, ['filePath'])
      
      this.log('删除文件', { filePath })

      const result = await this.invoke<{ success: boolean; error?: string }>('delete-file', filePath)
      
      if (result.success) {
        this.log('删除文件成功', { filePath })
        return createSuccessResult(undefined, '文件删除成功')
      } else {
        throw new Error(result.error || '文件删除失败')
      }

    } catch (error) {
      this.logError('删除文件', error, { filePath })
      return createErrorResult(error, '删除文件失败')
    }
  }

  /**
   * 导入资源文件
   */
  async importAssets(files: string[], projectId?: string): Promise<ServiceResult<AssetData[]>> {
    try {
      this.validateRequired({ files }, ['files'])
      
      if (!Array.isArray(files) || files.length === 0) {
        throw new Error('文件列表不能为空')
      }

      this.log('导入资源文件', { fileCount: files.length, projectId })

      const result = await this.invoke<AssetData[]>('asset:import', { files, projectId })
      
      this.log('导入资源文件成功', { importedCount: result.length })
      return createSuccessResult(result, `成功导入 ${result.length} 个资源文件`)

    } catch (error) {
      this.logError('导入资源文件', error, { files, projectId })
      return createErrorResult(error, '导入资源文件失败')
    }
  }

  /**
   * 获取资源列表
   */
  async getAssetList(options: {
    type?: 'image' | 'audio' | 'video' | 'all'
    projectId?: string
  } = {}): Promise<ServiceResult<AssetData[]>> {
    try {
      this.log('获取资源列表', options)

      const result = await this.invoke<AssetData[]>('asset:list', options)
      
      this.log('获取资源列表成功', { count: result.length, type: options.type })
      return createSuccessResult(result, `获取到 ${result.length} 个资源`)

    } catch (error) {
      this.logError('获取资源列表', error, options)
      return createErrorResult(error, '获取资源列表失败')
    }
  }

  /**
   * 删除资源
   */
  async deleteAsset(id: string): Promise<ServiceResult<boolean>> {
    try {
      this.validateRequired({ id }, ['id'])
      
      this.log('删除资源', { id })

      const result = await this.invoke<boolean>('asset:delete', { id })
      
      this.log('删除资源成功', { id })
      return createSuccessResult(result, '资源删除成功')

    } catch (error) {
      this.logError('删除资源', error, { id })
      return createErrorResult(error, '删除资源失败')
    }
  }

  /**
   * 格式化文件大小
   */
  formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B'
    
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  /**
   * 获取文件扩展名
   */
  getFileExtension(fileName: string): string {
    return fileName.split('.').pop()?.toLowerCase() || ''
  }

  /**
   * 判断是否为图片文件
   */
  isImageFile(fileName: string): boolean {
    const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
    return imageExtensions.includes(this.getFileExtension(fileName))
  }

  /**
   * 判断是否为音频文件
   */
  isAudioFile(fileName: string): boolean {
    const audioExtensions = ['mp3', 'wav', 'ogg', 'aac', 'flac', 'm4a']
    return audioExtensions.includes(this.getFileExtension(fileName))
  }

  /**
   * 判断是否为视频文件
   */
  isVideoFile(fileName: string): boolean {
    const videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv']
    return videoExtensions.includes(this.getFileExtension(fileName))
  }
}

// 导出单例实例
export const fileService = new FileService()

// 导出便捷方法
export const {
  getAppDataPath,
  readFile,
  writeFile,
  fileExists,
  getFileInfo,
  listDirectory,
  deleteFile,
  importAssets,
  getAssetList,
  deleteAsset,
  formatFileSize,
  getFileExtension,
  isImageFile,
  isAudioFile,
  isVideoFile
} = fileService
